// OpenFileDlg.cpp : implementation file
//

#include "stdafx.h"
#include "LoPlayer.h"
#include "OpenFileDlg.h"
#include <dlgs.h>

// COpenFileDlg
#define __DUMMY__ _T("*.*")
bool COpenFileDlg::m_fAllowDirSelection = true;
WNDPROC COpenFileDlg::m_wndProc = NULL;

IMPLEMENT_DYNAMIC(COpenFileDlg, CFileDialog)

COpenFileDlg::COpenFileDlg(LPCTSTR lpszFilter,
						   const CStringArray& aStrMask, CWnd* pParentWnd /*= NULL*/, LPCTSTR lpszFileName /*= NULL*/, LPCTSTR lpszDefExt /*= NULL*/, DWORD dwFlags /*= OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST|OFN_HIDEREADONLY*/, BOOL bOpenFileDialog /*= TRUE /* TRUE for FileOpen, FALSE for FileSaveAs */ )
		: CFileDialog(bOpenFileDialog, lpszDefExt, lpszFileName, dwFlags, lpszFilter, pParentWnd)
		, m_asMask(aStrMask)
{
	const int c_cMaxFiles = 1000;
	const int c_cbBuffSize = (c_cMaxFiles * (MAX_PATH + 1)) + 1;
	m_buff.Allocate(c_cbBuffSize);m_buff[0] = 0;

	GetOFN().lpstrFile	= m_buff;
	GetOFN().nMaxFile	= c_cMaxFiles;
	GetOFN().lpstrInitialDir = lpszFileName;
}

//=============================================================================
COpenFileDlg::~COpenFileDlg()
{
}


BEGIN_MESSAGE_MAP(COpenFileDlg, CFileDialog)
	ON_WM_DESTROY()
END_MESSAGE_MAP()


// COpenFileDlg message handlers

LRESULT CALLBACK COpenFileDlg::WindowProcNew(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	if (message ==  WM_COMMAND && HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDOK
			&& m_fAllowDirSelection) {
		CAutoVectorPtr<TCHAR> path;
		path.Allocate(MAX_PATH + 1); // MAX_PATH should be bigger for multiple selection, but we are only interested if it's zero length
		// note: allocating MAX_PATH only will cause a buffer overrun for too long strings, and will result in a silent app disappearing crash, 100% reproducable
		if (::GetDlgItemText(hwnd, cmb13, (TCHAR*)path, MAX_PATH) == 0)
			::SendMessage(hwnd, CDM_SETCONTROLTEXT, edt1, (LPARAM)__DUMMY__);
	}

	return CallWindowProc(COpenFileDlg::m_wndProc, hwnd, message, wParam, lParam);
}

BOOL COpenFileDlg::OnInitDialog()
{
	CFileDialog::OnInitDialog();

#ifdef WIN64
	m_wndProc = (WNDPROC)SetWindowLong(GetParent()->m_hWnd, GWLP_WNDPROC , (LONG)WindowProcNew);
#else
	m_wndProc = (WNDPROC)SetWindowLong(GetParent()->m_hWnd, GWL_WNDPROC, (LONG)WindowProcNew);
#endif

	return TRUE;  // return TRUE unless you set the focus to a control
	// EXCEPTION: OCX Property Pages should return FALSE
}

void COpenFileDlg::OnDestroy()
{
	int i = GetPathName().Find(__DUMMY__);
	if (i >= 0) m_pOFN->lpstrFile[i] = m_pOFN->lpstrFile[i+1] = 0;

	CFileDialog::OnDestroy();
}

BOOL COpenFileDlg::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
	ASSERT(pResult != NULL);

	OFNOTIFY* pNotify = (OFNOTIFY*)lParam;
	// allow message map to override
	if (__super::OnNotify(wParam, lParam, pResult)) {
		ASSERT(pNotify->hdr.code != CDN_INCLUDEITEM);
		return TRUE;
	}

	switch (pNotify->hdr.code) {
	case CDN_INCLUDEITEM:
		if (OnIncludeItem((OFNOTIFYEX*)lParam, pResult))
			return TRUE;
		break;
	}

	return FALSE;   // not handled
}

BOOL COpenFileDlg::OnIncludeItem(OFNOTIFYEX* pOFNEx, LRESULT* pResult)
{
	TCHAR buff[MAX_PATH];
	if (!SHGetPathFromIDList((LPCITEMIDLIST)pOFNEx->pidl, buff)) {
		STRRET s;
		HRESULT hr = ((IShellFolder*)pOFNEx->psf)->GetDisplayNameOf((LPCITEMIDLIST)pOFNEx->pidl, SHGDN_NORMAL | SHGDN_FORPARSING, &s);
		if (S_OK != hr) return FALSE;
		switch (s.uType) {
		case STRRET_CSTR:
			_tcscpy(buff, CString(s.cStr));
			break;
		case STRRET_WSTR:
			_tcscpy(buff, CString(s.pOleStr));
			CoTaskMemFree(s.pOleStr);
			break;
		default:
			return FALSE;
		}
	}

	CString fn(buff);
	/*
		WIN32_FILE_ATTRIBUTE_DATA fad;
		if(GetFileAttributesEx(fn, GetFileExInfoStandard, &fad)
		&& (fad.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY))
			return FALSE;
	*/
	int i = fn.ReverseFind('.'), j = fn.ReverseFind('\\');
	if (i < 0 || i < j)
		return FALSE;

	CString mask = m_asMask[pOFNEx->lpOFN->nFilterIndex-1] + _T(";");
	CString ext = fn.Mid(i).MakeLower() + _T(";");

	*pResult = mask.Find(ext) >= 0 || mask.Find(_T("*.*")) >= 0;

	return TRUE;
}
